package com.sz.common.base.utils;

import com.sz.common.base.exception.CommonErrorCodes;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.logger.Logger;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtils {
    public static final int DATE_LEN = 19;
    private static Logger logger = Logger.getLogger(DateUtils.class);
    public static final String FORMAT_DETAIL = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_SIMPLE = "yyyy-MM-dd";
    public static final String FORMAT_MEDIUM = "yyyy-MM-dd HH:mm";

    public static String formatDateForBillingTaskCode(Date date) {
        return formatDate(date, "yyMMdd");
    }

    public static String formatDetailDate(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static Date parseDetailDate(String date) throws ParseException {
        return parseDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String formatSimpleDate(Date date) {

        return formatDate(date, "yyyy-MM-dd");
    }

    public static String formatMediumDate(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm");
    }

    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat ft = new SimpleDateFormat(pattern);
        return ft.format(date);
    }

    public static Date parseDate(String date, String pattern) throws ParseException {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        SimpleDateFormat ft = new SimpleDateFormat(pattern);
        return ft.parse(date);
    }

    public static Date convertToDate(String dateStr, String pattern) throws ParseException {
        SimpleDateFormat ft = new SimpleDateFormat(pattern);
        return ft.parse(dateStr);
    }

    public static Date getDayBegin(Date day) throws ParseException {
        return convertToDate(formatSimpleDate(day) + " 00:00:00", FORMAT_DETAIL);
    }

    public static Date getDayEnd(Date day) throws ParseException {
        return convertToDate(formatSimpleDate(day) + " 23:59:59", FORMAT_DETAIL);
    }

    public static int getDateDaysDiff(Date start, Date end) {
        int days = (int) ((end.getTime() - start.getTime()) / 86400000);
        return days;
    }

    public static Date getFinalDate() {
        try {
            return convertToDate("2100-01-01 00:00:00", FORMAT_DETAIL);
        } catch (Exception ex) {
            // Do nothing
        }
        return null;
    }

    /**
     * 判断某一时间是否在一个时间段内，前后端闭区间，包括两端的时间点
     *
     * @param date      被判断的时间点
     * @param beginDate 时间段的开始时间
     * @param endDate   时间段的结束时间
     * @return true:在范围之内 false：在时间段之外
     */
    public static boolean isInDate(Date date, Date beginDate, Date endDate) {
        if (date == null) {
            throw Exceptions.bizException(CommonErrorCodes.ERROR_ARGUMENT_EMPTY, "date");
        }
        if (beginDate == null) {
            throw Exceptions.bizException(CommonErrorCodes.ERROR_ARGUMENT_EMPTY, "beginDate");
        }
        if (endDate == null) {
            throw Exceptions.bizException(CommonErrorCodes.ERROR_ARGUMENT_EMPTY, "endDate");
        }
        return (date.after(beginDate) && date.before(endDate))
                || date.compareTo(beginDate) == 0
                || date.compareTo(endDate) == 0;
    }


    public static Date parseDetailDateTime(String messageTimeStr) {
        if (StringUtils.isEmpty(messageTimeStr) || messageTimeStr.length() != DATE_LEN) {
            logger.error("日期格式有问题" + messageTimeStr);
            throw Exceptions.bizException(CommonErrorCodes.ERROR_COMMON, "日期格式有问题");
        }
        try {
            return DateUtils.parseDetailDate(messageTimeStr);
        } catch (ParseException e) {
            logger.error("日期解析出错", e);
            throw Exceptions.bizException(CommonErrorCodes.ERROR_COMMON, "日期格式有问题");
        }
    }

    /***
     * 获取上个月的第一天
     */
    public static Date getLastMonthFirstDay() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, -1);
        return getDayBegin(calendar.getTime());
    }

    /***
     * 获取上个月的最后一天
     */
    public static Date getLastMonthLastDay() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return getDayBegin(calendar.getTime());
    }
    /***
     * 获取上个周的第一天
     */
    public static Date getLastWeekFirstDay() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        int offset = 1 - dayOfWeek;
        calendar.add(Calendar.DATE, offset - 7);
        return getDayBegin(calendar.getTime());
    }

    /***
     * 获取上个周的最后一天
     */
    public static Date getLastWeekLastDay() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        int offset = 7 - dayOfWeek;
        calendar.add(Calendar.DATE, offset - 7);
        return getDayBegin(calendar.getTime());
    }

    /**
     * 返回上季的第一天
     * 0 1 2    Q1   /3=0  1月
     * 3 4 5    Q2   /3=1  4月
     * 6 7 8    Q3   /3=2  7月
     * 9 10 11  Q4   /3=3  10月
     */
    public static Date getFirstDayOfLastQuarter() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        int month = 0;
        int quarter = calendar.get(Calendar.MONTH) / 3;
        int year = calendar.get(Calendar.YEAR);
        if (quarter == 0) {
            month = 9;
            year--;
        } else if (quarter == 1) {
            month = 0;
        } else if (quarter == 2) {
            month = 3;
        } else if (quarter == 3) {
            month = 6;
        }
        calendar.clear();
        calendar.set(year, month, 1);
        return getDayBegin(calendar.getTime());
    }

    /**
     * 返回上个季的最后一天
     * 0 1 2    Q1   /3=0   3月
     * 3 4 5    Q2   /3=1   6月
     * 6 7 8    Q3   /3=2   9月
     * 9 10 11  Q4   /3=3   12月
     */
    public static Date getLastDayOfLastQuarter() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = 0;
        //当前季
        int quarter = calendar.get(Calendar.MONTH) / 3;
        if (quarter == 0) {
            month = 11;
            year--;
        } else if (quarter == 1) {
            month = 2;
        } else if (quarter == 2) {
            month = 5;
        } else if (quarter == 3) {
            month = 8;
        }
        calendar.clear();
        calendar.set(year, month, 1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return getDayBegin(calendar.getTime());
    }

    /***
     * 获取上个年的第一天
     */
    public static Date getLastYearFirstDay() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.MONTH, 0);
        calendar.add(Calendar.YEAR, -1);
        return getDayBegin(calendar.getTime());
    }

    /***
     * 获取上个年的最后一天
     */
    public static Date getLastYearLastDay() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 31);
        calendar.set(Calendar.MONTH, 11);
        calendar.add(Calendar.YEAR, -1);
        return getDayBegin(calendar.getTime());
    }


}
